package mygame;

import character.AbstractCharacter;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import gameobject.construct.Construct;

public abstract class WorldManager {
    
    public static void addCharacterToWorld(AbstractCharacter character) {
	DataStore.worldStateNode.getHubNodeCharacter().attachChild(character);
        DataStore.bulletAppState.getPhysicsSpace().addAll(character);
	DataStore.aiAppState.getAISpace().addAll(character);
    }

    /**
     * Adds a construct to the world by first "instantiating" it. This means it brings the construct into physical being,
     * adding physics and also adding all of its occupied voxels to the voxel grid.
     */
    public static void addConstructToWorld(Construct construct, Node onNode) {
	construct.instantiate();
	for(Voxel occupiedVoxel : construct.getOccupiedVoxels()) {
            //be safe! make sure there isn't already a voxel there before doing this
	    DataStore.worldStateNode.getVoxelGrid().addVoxel(occupiedVoxel);
	}
	DataStore.bulletAppState.getPhysicsSpace().addAll(construct);
	onNode.attachChild(construct);
	construct.setSavedParent(onNode);
    }

    public static void addConstructToWorldTemporary(Construct construct) {
	DataStore.tempNode.attachChild(construct);
    }
    
    /**
     * Recurses through a chunk, which can house any number of nodes and Constructs,
     * adding each Construct to the world. Nodes are ignored and are NOT added to the world.
     * NOTE: All Constructs will be REMOVED from the chunk when this method completes.
     */
    public static void addChunkToWorld(Node chunk) {
        //recurse through chunk, calling addConstructToWorld for each Construct
        for(Spatial child : chunk.getChildren()) {
            if(child instanceof Construct) {
                addConstructToWorld((Construct)child, DataStore.worldStateNode.getHubNodeUnselectableConstruct());
            } else if(child instanceof Node) {
                addChunkToWorld((Node)child);
            }
        }
    }

    public static void removeConstructFromWorld(Construct construct) {
        for(Voxel occupiedVoxel : construct.getOccupiedVoxels()) {
	    DataStore.worldStateNode.getVoxelGrid().removeVoxel(occupiedVoxel);
	}
	DataStore.bulletAppState.getPhysicsSpace().removeAll(construct);
	construct.removeFromParent();
    }
}
